package dao;

import entity.Contact;
import entity.IEntity;
import entity.Student;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaQuery;

/**
 *
 * @author Alexander
 */
public class ContactDAO implements IDAO {

    @Override
    public void persist(IEntity entity, EntityManager em) {
        em.persist(entity);
    }

    @Override
    public IEntity find(Object id, EntityManager em) {
        return (Contact) em.find(Contact.class, (int) id);
    }

    @Override
    public void update(IEntity entity, EntityManager em) {
        em.merge(entity);
    }

    @Override
    public void delete(Object id, EntityManager em) {
        Contact contact = (Contact) em.getReference(Contact.class, (int) id);
        em.remove(contact);
    }

    @Override
    public List<IEntity> getList(EntityManager em) {
        CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
        cq.select(cq.from(Contact.class));
        Query q = em.createQuery(cq);
        return q.getResultList();
    }
    /**
     * Busca la lista de contactos de un usuario
     * @param user Usuario registrado
     * @param name Nombre del contacto
     * @param em Manager de persistencia
     * @return Lista de contactos del usuario
     */
    public List<Contact> findByUser(Student user, String name, EntityManager em){
        List<Contact> cont = new ArrayList<>();
        Query q = em.createQuery("SELECT c "
                + "FROM Contact c "
                + "WHERE c.student = :user "
                        + "AND "
                    + "(LOWER(c.name) LIKE :cont "
                        + "OR LOWER(c.lastName) LIKE :cont "
                        + "OR LOWER(CONCAT(c.name, ' ', c.lastName)) LIKE :cont)")
                .setParameter("user", user).setParameter("cont", name.toLowerCase() + "%");
        
        cont = q.getResultList();
        
        return cont;
    }
    
    /**
     * Busca la lista de telefonos de un contacto de un usuario
     * @param user Usuario registrado
     * @param cont Contacto del usuario
     * @param em Manager de persistencia
     * @return Lista de telefonos del contacto
     */
    public List<Double> phoneList(Student user, String cont, EntityManager em){
        List<Double> phone = null;
        Query q = em.createQuery("SELECT c.phones "
                + "FROM Contact c "
                + "WHERE c.student = :user "
                + "AND CONCAT(c.name,c.lastName) = :name").setParameter("user", user).setParameter("name", cont);
        
        phone = (List<Double>) q.getResultList().get(0);
        
        return phone;
    }
    
    /**
     * Busca un contacto del usuario activo
     * @param user Usuario activo
     * @param cont Nombre del contacto
     * @param em Manager de la persistencia
     * @return El contacto buscado
     */
    public IEntity findContact(Student user, String cont, EntityManager em){
        Contact con = null;
        Query q = em.createQuery("SELECT c "
                + "FROM Contact c "
                + "WHERE c.student.username = :user "
                + "AND CONCAT(c.name,c.lastName) = :name").setParameter("user", user.getUsername()).setParameter("name", cont);
        
        con = (Contact) q.getSingleResult();
        
        return con;
    }
}
